package com.ly.crawl.impl;


import com.ly.crawl.DataDao;

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DownDataDao<T> implements DataDao<T> {

    private final String table;
    private final PrintWriter out;
    private final String[] columns;
    private Map<String, Integer> columnLengthMap = new HashMap<>();

    public DownDataDao(PrintWriter out, String table, String... columns) {
        this.out = out;
        this.table = table;
        this.columns = new String[columns.length + 1];
        System.arraycopy(columns, 0, this.columns, 0, columns.length);
        this.columns[this.columns.length - 1] = "url";
    }

    public void createTable() {
        String sql = "create table " + table + "(\n";
        if (Arrays.stream(columns).anyMatch(c -> c.equals("id")) == false) {
            sql += "`id` int(11) NOT NULL auto_increment\n";
        }
        for (String column : columns) {
            column = castColumnName(column);
            if ("id".equals(column) == false) {
                Integer length = columnLengthMap.get(column);
                sql += ",`" + column + "` varchar(" + (length == null ? 255 : length) + ")\n";
            }
        }
        sql += ",PRIMARY KEY  (`id`));";
        out.println(sql);
    }

    @Override
    public void save(T data) {
        List<Map<String, Object>> list;
        if (data instanceof List) {
            list = (List<Map<String, Object>>) data;
            for (Map<String, Object> row : list) {
                saveRow(row);
            }
        } else {
            saveRow((Map<String, Object>) data);
        }
    }

    private void saveRow(Map<String, Object> data) {
        String insert = "insert into %s ( %s ) values ( %s );";
        StringBuilder cols = new StringBuilder();
        StringBuilder vals = new StringBuilder();
        if (!data.containsKey("id")) {
            cols.append("id");
            vals.append("default");
        }
        for (Map.Entry<String, Object> en : data.entrySet()) {
            cols.append(cols.length() == 0 ? "" : ",");
            vals.append(vals.length() == 0 ? "" : ",");
            cols.append(castColumnName(en.getKey()));
            if (en.getValue() instanceof String) {
                Integer length = columnLengthMap.get(en.getKey());
                if (length == null || length < ((String) en.getValue()).length()) {
                    length = ((String) en.getValue()).length();
                }
                columnLengthMap.put(en.getKey(), length);
            }
            Object value = en.getValue();
            if (value instanceof String) {
                // 替换单引号, 转义
                value = ((String) value).replaceAll("'", "''");
            }
            vals.append("'" + value + "'");
        }
        insert = String.format(insert, table, cols, vals);
        out.println(insert);
    }

    private String castColumnName(String columnName) {
        if (columnName.endsWith("*")) {
            return columnName.substring(0, columnName.length() - 1);
        } else {
            return columnName;
        }
    }

    @Override
    public void after() {
        out.println("/* 建表语句, 请复制语句, 手动完成建表.\n");
        createTable();
        out.println("\n*/");
    }
}
